package com.jzo2o.customer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.customer.dto.response.AddressBookResDTO;
import com.jzo2o.api.publics.MapApi;
import com.jzo2o.api.publics.dto.response.LocationResDTO;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.NumberUtils;
import com.jzo2o.common.utils.StringUtils;
import com.jzo2o.customer.mapper.AddressBookMapper;
import com.jzo2o.customer.model.domain.AddressBook;
import com.jzo2o.customer.model.dto.request.AddressBookPageQueryReqDTO;
import com.jzo2o.customer.model.dto.request.AddressBookUpsertReqDTO;
import com.jzo2o.customer.service.IAddressBookService;
import com.jzo2o.mvc.utils.UserContext;
import com.jzo2o.mysql.utils.PageHelperUtils;
import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 地址薄 服务实现类
 * </p>
 *
 * @author itcast
 * @since 2023-07-06
 */
@Service
public class AddressBookServiceImpl extends ServiceImpl<AddressBookMapper, AddressBook> implements IAddressBookService {

    @Autowired
    private MapApi mapApi;
    @Override
    public List<AddressBookResDTO> getByUserIdAndCity(Long userId, String city) {

        List<AddressBook> addressBooks = lambdaQuery()
                .eq(AddressBook::getUserId, userId)
                .eq(AddressBook::getCity, city)
                .list();
        if(CollUtils.isEmpty(addressBooks)) {
            return new ArrayList<>();
        }
        return BeanUtils.copyToList(addressBooks, AddressBookResDTO.class);
    }

    /**
     * 获取默认地址
     *
     * @return 默认地址信息
     */
    @Override
    public AddressBookResDTO defaultAddress() {
        //查询默认地址信息
        AddressBook addressBook = this.lambdaQuery().eq(AddressBook::getIsDefault, 1)
                .eq(AddressBook::getUserId, UserContext.currentUserId())
                .one();
        if (ObjectUtil.isNull(addressBook)) {
            return null;
        }
        AddressBookResDTO bookResDTO = BeanUtil.toBean(addressBook, AddressBookResDTO.class);
        return bookResDTO;
    }

    /**
     * 新增地址簿
     *
     * @param dto 前端传来的新增地址信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertAddress(AddressBookUpsertReqDTO dto) {
        //健壮性判断
        if (ObjectUtil.isNull(dto)) {
            return;
        }
        //判断是否添加的是默认地址
        if (dto.getIsDefault() == 1) {
            //查询该用户的所有地址
            List<AddressBook> addressBooks = baseMapper.selectList(Wrappers.<AddressBook>lambdaQuery().eq(AddressBook::getUserId, UserContext.currentUserId()));
            //遍历
            for (AddressBook addressBook : addressBooks) {
                //将当前用户的所有地址修改为非默认地址
                addressBook.setIsDefault(0);
                baseMapper.updateById(addressBook);
            }
            //将当前地址改为默认地址
            AddressBook addressBook = BeanUtil.toBean(dto, AddressBook.class);
            String location = dto.getLocation();
            addressBook.setUserId(UserContext.currentUserId());
            getLocation(dto, location, addressBook);
            baseMapper.insert(addressBook);
        }else {
            AddressBook addressBook = BeanUtil.toBean(dto, AddressBook.class);
            String location = dto.getLocation();
            getLocation(dto, location, addressBook);
            addressBook.setUserId(UserContext.currentUserId());
            baseMapper.insert(addressBook);
        }
    }
    //补全经纬度
    private void getLocation(AddressBookUpsertReqDTO dto, String location, AddressBook addressBook) {
        if (StringUtils.isNotBlank(location)) {
            String[] split = location.split(",");
            addressBook.setLon(Double.parseDouble(split[0]));
            addressBook.setLat(Double.parseDouble(split[1]));
        }else {
            LocationResDTO locationResDTO = mapApi.getLocationByAddress(dto.getAddress());
            String[] split = locationResDTO.getLocation().split(",");
            addressBook.setLon(Double.parseDouble(split[0]));
            addressBook.setLat(Double.parseDouble(split[1]));

        }
    }

    /**
     * 地址簿列表
     *
     * @param dto 前端传来分页信息
     * @return 地址簿列表
     */
    @Override
    public PageResult<AddressBook> addressPage(AddressBookPageQueryReqDTO dto) {
        // 1. 将前端传入的分页参数DTO转换为MyBatis-Plus的Page对象
        // dto: 前端传入的分页参数对象(包含pageNum/pageSize等)
        // AddressBook.class: 指定分页查询的实体类型
        Page<AddressBook> page = PageUtils.parsePageQuery(dto, AddressBook.class);
        // 2. 执行分页查询
        // baseMapper: MyBatis-Plus的BaseMapper接口实现
        // selectPage: MyBatis-Plus提供的分页查询方法
        Page<AddressBook> selectPage = baseMapper.selectPage(page, Wrappers.<AddressBook>lambdaQuery().eq(AddressBook::getUserId, UserContext.currentUserId()));
        //3. 将MyBatis-Plus的分页结果转换为自定义的PageResult对象返回
        // selectPage.getPages(): 总页数
        // selectPage.getTotal(): 总记录数
        // selectPage.getRecords(): 当前页数据列表
        return new PageResult<>(selectPage.getPages(), selectPage.getTotal(), selectPage.getRecords());


    }

    /**
     * 地址簿详情
     *
     * @param id 地址id
     * @return
     */
    @Override
    public AddressBook addressDetails(Long id) {
        //根据ID查询地址
        AddressBook addressBook = baseMapper.selectById(id);
        if (ObjectUtil.isNull(addressBook)) {
            return null;
        }
        return addressBook;
    }

    /**
     * 地址簿编辑
     *
     * @param dto 修改的信 息
     * @param id  地址id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateAddress(AddressBookUpsertReqDTO dto, Long id) {
        //健壮性判断
        if (ObjectUtil.isNull(dto)) {
            return;
        }
        //判断是否修改为默认地址
        if (dto.getIsDefault() == 1) {
            //查询该用户的所有地址
            List<AddressBook> addressBooks = baseMapper.selectList(Wrappers.<AddressBook>lambdaQuery().eq(AddressBook::getUserId, UserContext.currentUserId()));
            //遍历
            for (AddressBook addressBook : addressBooks) {
                //将当前用户的所有地址修改为非默认地址
                addressBook.setIsDefault(0);
                baseMapper.updateById(addressBook);
            }
            //将当前地址改为默认地址
            AddressBook addressBook = BeanUtil.toBean(dto, AddressBook.class);
            addressBook.setId(id);
            String location = dto.getLocation();
            getLocation(dto, location, addressBook);
            baseMapper.updateById(addressBook);
        }else {
            AddressBook addressBook = BeanUtil.toBean(dto, AddressBook.class);
            addressBook.setId(id);
            String location = dto.getLocation();
            getLocation(dto, location, addressBook);
            baseMapper.updateById(addressBook);
        }
    }

    /**
     * 地址簿删除
     *
     * @param ids 地址id集合
     */
    @Override
    public void batchDelete(List<Long> ids) {
        //健壮性判断
        if (ObjectUtil.isNull(ids)) {
            return;
        }
        baseMapper.deleteBatchIds(ids);
    }

    /**
     * 设置默认地址
     *
     * @param flag 是否是默认地址
     * @param id   地址id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void defaultAddr(Long flag, Long id) {
        //健壮性判断
        if (ObjectUtil.isNull(flag) || id == null) {
            return;
        }
        //根据flag判断，是否是默认地址
        AddressBook addressBook = new AddressBook();
        if (flag == 1) {
            //查询该用户的所有地址并且将其改为非默认地址
            List<AddressBook> addressBooks = baseMapper.selectList(Wrappers.<AddressBook>lambdaQuery().eq(AddressBook::getUserId, UserContext.currentUserId()));
            for (AddressBook addr : addressBooks) {
                //将当前用户的所有地址修改为非默认地址
                addr.setIsDefault(0);
                baseMapper.updateById(addr);
            }

            addressBook.setId(id);
            addressBook.setIsDefault(Integer.valueOf(flag.toString()));
            baseMapper.updateById(addressBook);
        }else {
            addressBook.setId(id);
            addressBook.setIsDefault(Integer.valueOf(flag.toString()));
            baseMapper.updateById(addressBook);
        }
    }
}
